﻿using Enyim.Caching;
using Enyim.Caching.Memcached;
using Enyim.Caching.Memcached.Results;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace conMemcache
{
    /// <summary>
    /// created by Grissom at 2016-10-09 12:00:00
    /// memcached 缓存处理器
    /// </summary>
    public class MemcachedCacheHandle
    {
        //ICacheManager 
        private static MemcachedClient _client;
        public MemcachedCacheHandle()
        {
            //     if (_client == null)
            //         _client = CacheFactory.Build("memcached", settings => settings
            //.WithMemcachedCacheHandle("enyim.com/memcached"));
            if (_client == null)
            {
                _client = new MemcachedClient();

            }
        }
        public bool Add(string key, object value)
        {
            return this.Store(StoreMode.Add, key, value).Success;
        }

        public bool Add(string key, object value, int seconds)
        {
            var expiredTime = DateTime.Now.AddSeconds(seconds);
            return this.Store(StoreMode.Add, key, value, expiredTime).Success;
        }

        public void Clear()
        {
            _client.FlushAll();
        }

        public string Get(string key)
        {
            return _client.Get<object>(key) + "";
        }

        public T Get<T>(string key)
        {
            try
            {
                return _client.Get<T>(key);
            }
            catch (Exception ex)
            {
                return default(T);
            }
            //return default(T);
            //throw new NotImplementedException();
        }

        public void Put(string key, object value)
        {
            this.Store(StoreMode.Set, key, value);
            //throw new NotImplementedException();
        }

        public void Put(string key, object value, int seconds)
        {
            this.Store(StoreMode.Set, key, value, DateTime.Now.AddSeconds(seconds));
        }

        public bool Remove(string key)
        {
            return _client.Remove(key);
        }


        private IStoreOperationResult Store(StoreMode storeMode, string key, object value)
        {
            return this.Store(storeMode, key, value, DateTime.MinValue);
        }

        private IStoreOperationResult Store(StoreMode operationMode, string key, object value, DateTime expiredTime)
        {
            if (DateTime.MinValue == expiredTime)
            {
                return _client.ExecuteStore(operationMode, key, value);
            }
            else
            {
                return _client.ExecuteStore(operationMode, key, value, expiredTime);
            }
        }

        private static string GetKey(string key, string region = null)
        {
            var fullKey = key;

            if (!string.IsNullOrWhiteSpace(region))
            {
                fullKey = string.Concat(region, ":", key);
            }

            // Memcached still has a 250 character limit
            if (fullKey.Length >= 250)
            {
                return GetSHA256Key(fullKey);
            }

            return fullKey;
        }

        private static string GetSHA256Key(string key)
        {
            using (var sha = SHA256Managed.Create())
            {
                byte[] hashBytes = sha.ComputeHash(Encoding.UTF8.GetBytes(key));
                return Convert.ToBase64String(hashBytes);
            }
        }

    }
}
